package com.gimi.cloud.jimi.client.service.moreInfo.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gimi.cloud.jimi.client.service.moreInfo.CreditcardBankcodeService;
import com.gimi.cloud.jimi.common.enums.ResponseCodeEnum;
import com.gimi.cloud.jimi.common.exception.MsgException;
import com.gimi.cloud.jimi.common.mq.service.MqCommonSenderService;
import com.gimi.cloud.jimi.common.utils.DateUtil;
import com.gimi.cloud.jimi.common.utils.reqhead.Response;
import com.gimi.cloud.jimi.commonService.InterfacePlatform.InterfacePlatformRequestService;
import com.gimi.cloud.jimi.common.mq.enume.QueueEnum;
import com.gimi.cloud.jimi.dao.dao.User.UserDao;
import com.gimi.cloud.jimi.dao.dao.moreInfo.CreditcardBankcodeDao;
import com.gimi.cloud.jimi.dao.dao.moreInfo.MoreInfoDao;
import com.gimi.cloud.jimi.dao.dao.sys.SysConfigDao;
import com.gimi.cloud.jimi.dto.app.moreInfo.CreditcardBankcodeDTO;
import com.gimi.cloud.jimi.dto.app.moreInfo.CreditcardLoginDTO;
import com.gimi.cloud.jimi.entity.app.moreInfo.MoreInfoEntity;
import com.gimi.cloud.jimi.entity.user.User;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @auther loongs
 * @date 2018/1/12  13:30
 */
@Service
public class CreditcardBankcodeServiceImpl implements CreditcardBankcodeService {
    private static final Logger log = LoggerFactory.getLogger(CreditcardBankcodeServiceImpl.class);
    private final static String INTERFACE_PLATFORM_UNIVERSAL_CREDITCARDWATER = "interface_platform_universal_creditCardWater";

    private CreditcardBankcodeDao creditcardBankcodeDao;
    private InterfacePlatformRequestService ipRequestService;
    private SysConfigDao sysConfigDao;
    private MoreInfoDao moreInfoDao;
    private MqCommonSenderService commonSenderService;
    private UserDao userDao;
    //最大容错次数暂时定为3次
    private final Integer MAXTIMES = 3;
    @Autowired
    public CreditcardBankcodeServiceImpl(CreditcardBankcodeDao creditcardBankcodeDao, InterfacePlatformRequestService ipRequestService,
                                         SysConfigDao sysConfigDao, MoreInfoDao moreInfoDao, MqCommonSenderService commonSenderService,UserDao userDao) {
        this.creditcardBankcodeDao = creditcardBankcodeDao;
        this.ipRequestService = ipRequestService;
        this.sysConfigDao = sysConfigDao;
        this.moreInfoDao = moreInfoDao;
        this.commonSenderService = commonSenderService;
        this.userDao=userDao;
    }

    @Override
    public Response getSupportedCreditcardBanks(CreditcardBankcodeDTO creditcardBankcodeDTO) {
        Map<String, Object> map = new HashMap<>();
        Response response = new Response();
        map.put("bankList", creditcardBankcodeDao.selectSupportedBanks());
        response.setRes_data(map);
        response.setResponseCode(ResponseCodeEnum.SUCCESSED);
        return response;
    }

    @Override
    public Response getCreditcardLoginParameter(CreditcardBankcodeDTO creditcardBankcodeDTO) {
        Map<String, Object> map = new HashMap<>();
        Response response = new Response();
        map.put("bankParam", creditcardBankcodeDao.selectByPrimaryKey(creditcardBankcodeDTO.getFcbcId()));
        response.setRes_data(map);
        response.setResponseCode(ResponseCodeEnum.SUCCESSED);
        return response;
    }

    @Override
    public Response subCreditcardBasicParam(CreditcardLoginDTO creditcardLoginDTO) {
        log.info("开始发起信用卡网银登录");

        log.info("读取配置表并组装请求参数");
        String fengchao_gongjijing = sysConfigDao.getConfigByKey(INTERFACE_PLATFORM_UNIVERSAL_CREDITCARDWATER);
        JSONObject fgJson = JSON.parseObject(fengchao_gongjijing);
        JSONObject submitbasicinfo = fgJson.getJSONObject("fengchao_bankonline_submitbasicinfo");
        JSONObject body = submitbasicinfo.getJSONObject("body");
        body.put("bankCode", creditcardLoginDTO.getBankCode());
        body.put("args", creditcardLoginDTO.getLoginParameter());
        submitbasicinfo.put("body", body);

        Response response = new Response();
        try {
            log.info("提交基本参数尝试登陆");
            String sendApiPost = ipRequestService.sendApiPost(submitbasicinfo.toJSONString());
            JSONObject sessionJson = JSON.parseObject(sendApiPost);
            JSONObject sessionbody = sessionJson.getJSONObject("body");
            String sessionToken = sessionbody.getString("sessionToken");

            if (!"1".equals(sessionbody.getString("status")) || StringUtils.isBlank(sessionToken)) {
                response.setResponseCode(ResponseCodeEnum.LOGIN_EXCEPTION, sessionbody.getString("errors"));
                return response;
            }

            JSONObject getloginstatus = fgJson.getJSONObject("fengchao_bankonline_getloginstatus");
            JSONObject glBody = getloginstatus.getJSONObject("body");
            glBody.put("sessionToken", sessionToken);

            log.info("登录后返回的sessionToken：" + sessionToken);
            Integer operUserId = creditcardLoginDTO.getUserId();
            return getCreditcardLoginStatus(sessionToken, operUserId);
        } catch (Exception e) {
            log.info("基本参数登录异常" + e.getClass());
            e.printStackTrace();
            response.setResponseCode(ResponseCodeEnum.SERVICE_ERROR);
            return response;
        }
    }

    @Override
    public Response getCreditcardLoginStatus(String sessionToken, Integer operUserId) throws Exception {
        log.info("读取配置表并组装请求参数");
        String creditcardwater = sysConfigDao.getConfigByKey(INTERFACE_PLATFORM_UNIVERSAL_CREDITCARDWATER);
        JSONObject fgJson = JSON.parseObject(creditcardwater);
        JSONObject getloginstatus = fgJson.getJSONObject("fengchao_bankonline_getloginstatus");
        JSONObject glBody = getloginstatus.getJSONObject("body");
        glBody.put("sessionToken", sessionToken);
        getloginstatus.put("body", glBody);

        log.info("获取登录状态");
        String status = null;
        JSONObject glbody = null;
        Response response = new Response();
        do {
            //半秒调一次，此方法有待优化
            Thread.sleep(500);

            String glRep = ipRequestService.sendApiPost(getloginstatus.toJSONString());
            JSONObject glRepJson = JSON.parseObject(glRep);
            glbody = glRepJson.getJSONObject("body");
            status = glbody.getString("status");
        } while ("101".equals(status));

        if (status == null || "-1".equals(status)) {
            response.setResponseCode(ResponseCodeEnum.SERVICE_ERROR);
            return response;
        }

        response.setRes_data(glbody);
        switch (status) {
            case "000":
                log.info("报告解析完成等待获取");
                //初始化数据，并且封装数据发送到mq，
                //如果是000，sessionToken传入空值，mq那边直接抓取，不去查状态
                initMoreInfoAndSentToMq(operUserId,"",glbody);
                break;
            case "100":
            case "201":
                //初始化数据，并且封装数据发送到mq
                initMoreInfoAndSentToMq(operUserId,sessionToken,glbody);
                break;
            case "001":
                response.setResponseCode(ResponseCodeEnum.NEED_IMAGECODE_VALIDATION);
                return response;
            case "002":
                response.setResponseCode(ResponseCodeEnum.NEED_PHONECODE_VALIDATION);
                return response;
            case "003":
                response.setResponseCode(ResponseCodeEnum.NEED_VALIDATION);
                return response;
            default:
                response.setResponseCode(ResponseCodeEnum.LOGIN_EXCEPTION, glbody.getString("errors"));
                return response;
        }
        response.setResponseCode(ResponseCodeEnum.SUCCESSED);
        return response;
    }

    /**
     * 初始化数据
     * @param operUserId
     */
    private void initMoreInfoAndSentToMq(Integer operUserId,String sessionToken,JSONObject glbody) throws Exception {
        User user = userDao.getUserByUserId(operUserId);
        if (user == null) {
            throw new MsgException(ResponseCodeEnum.ERR_USER_INVALID);
        }
        //查询该用户之前是否有获取过信用卡流水，需要获取状态为获取中
        MoreInfoEntity moreInfoEntity = moreInfoDao.getMoreInfoByUserIdAndType(operUserId,4);

        //半段是不是新增，true是新增，false已存在
        boolean flag = false;

        //返回值为2的时候，是代表时间已经过期
        //为0代表过期时间字段为空
        if (moreInfoEntity != null && (DateUtil.compare(moreInfoEntity.getReportEffectionEnd(), DateUtil.getNow()) == 2 ||
                (DateUtil.compare(moreInfoEntity.getReportEffectionEnd(), DateUtil.getNow()) == 0 && !"2".equals(moreInfoEntity.getGetdata())))) {
            //如果是有效期内，就做修改，不做新增
            //如果是失败的且过期时间为空，就需要做修改，不做新增
        }else {
            //时间过期了的新增
            moreInfoEntity = new MoreInfoEntity();
            moreInfoEntity.setGetdataTime(new Date());
            moreInfoEntity.setAnalysis("0");

            //user相关
            moreInfoEntity.setAddTime(new Date());
            moreInfoEntity.setAddUname(user.getAddUname());
            moreInfoEntity.setAddUid(user.getUserId());
            moreInfoEntity.setUserId(user.getUserId());

            //4代表信用卡流水
            moreInfoEntity.setDataType("4");
            moreInfoEntity.setGetdataMaxTimes(MAXTIMES);

            flag = true;
        }

        //获取中
        moreInfoEntity.setGetdata("1");
        if(flag){
            moreInfoDao.insertSelective(moreInfoEntity);
        }else{
            moreInfoEntity.setUpdateUid(user.getUserId());
            moreInfoEntity.setUpdateUname(user.getAddUname());
            moreInfoEntity.setUpdateTime(DateUtil.getNow());
            moreInfoDao.updateByPrimaryKey(moreInfoEntity);
        }
        //封装发送到队列里的参数
        CreditcardLoginDTO  creditcardLoginDTO = new CreditcardLoginDTO();
        creditcardLoginDTO.setUserId(operUserId);
        creditcardLoginDTO.setSessionToken(sessionToken);
        creditcardLoginDTO.setSurnameSid(glbody.getString("surnameSid"));
        commonSenderService.sendMessage2Rabbitmq(QueueEnum.FENGCHAO_XINYONGKALIUSHUI_REPORT, creditcardLoginDTO);
    }

    @Override
    public Response subMissionVerifiCationCode(CreditcardLoginDTO creditcardLoginDTO) {
        log.info("开始发起信用卡网银提交动态参数");

        String sessionToken = creditcardLoginDTO.getSessionToken();
        log.info("读取配置表并组装请求参数");
        String fengchao_gongjijing = sysConfigDao.getConfigByKey(INTERFACE_PLATFORM_UNIVERSAL_CREDITCARDWATER);
        JSONObject fgJson = JSON.parseObject(fengchao_gongjijing);
        JSONObject submitdynamicparam = fgJson.getJSONObject("fengchao_bankonline_submitdynamicparam");
        JSONObject body = submitdynamicparam.getJSONObject("body");
        body.put("sessionToken", creditcardLoginDTO.getSessionToken());
        body.put("args", creditcardLoginDTO.getDynamicParameter());
        submitdynamicparam.put("body", body);

        log.info("提交动态参数");
        Response response = new Response();
        try {
            String sendApiPost = ipRequestService.sendApiPost(submitdynamicparam.toJSONString());
            JSONObject repJson = JSON.parseObject(sendApiPost);
            JSONObject repBody = repJson.getJSONObject("body");

            if (repBody == null) {
                response.setResponseCode(ResponseCodeEnum.SERVICE_ERROR, "第三方请求异常请再次尝试");
                return response;
            }

            if (!"1".equals(repBody.getString("status"))) {
                response.setResponseCode(ResponseCodeEnum.SERVICE_ERROR, repBody.getString("errors"));
                return response;
            }

            log.info("获取登录状态");
            String sessionToken2 = repBody.getString("sessionToken");
            sessionToken2 = StringUtils.isBlank(sessionToken2) ? sessionToken : sessionToken2;
            return getCreditcardLoginStatus(sessionToken2, creditcardLoginDTO.getUserId());
        } catch (Exception e) {
            log.error("提交动态参数错误");
            e.printStackTrace();
            response.setResponseCode(ResponseCodeEnum.SERVICE_ERROR);
            return response;
        }
    }

    @Override
    public Response submitDynamicParam(CreditcardLoginDTO creditcardLoginDTO) {
        log.info("开始发起信用卡网银刷新验证码接口");

        log.info("读取配置表并组装请求参数");
        String creditCardWater = sysConfigDao.getConfigByKey(INTERFACE_PLATFORM_UNIVERSAL_CREDITCARDWATER);
        JSONObject fgJson = JSON.parseObject(creditCardWater);
        JSONObject refreshdynamicparam = fgJson.getJSONObject("fengchao_bankonline_refreshdynamicparam");
        JSONObject body = refreshdynamicparam.getJSONObject("body");
        body.put("sessionToken", creditcardLoginDTO.getSessionToken());
        body.put("args", creditcardLoginDTO.getDynamicParameter());
        refreshdynamicparam.put("body", body);

        log.info("提交动态参数");
        Response response = new Response();
        try {
            String sendApiPost = ipRequestService.sendApiPost(refreshdynamicparam.toJSONString());
            JSONObject repJson = JSON.parseObject(sendApiPost);
            JSONObject repBody = repJson.getJSONObject("body");

            if (repBody == null) {
                response.setResponseCode(ResponseCodeEnum.SERVICE_ERROR, "第三方请求异常请再次尝试");
                return response;
            }
            response.setRes_data(repBody);
            response.setResponseCode(ResponseCodeEnum.SUCCESSED);
        } catch (Exception e) {
            log.error("提交动态参数错误");
            e.printStackTrace();
            response.setResponseCode(ResponseCodeEnum.SERVICE_ERROR);
            return response;
        }
        return response;
    }
}
